import { ControlBase } from "./ControlBase.js";

export class StatusBarControl extends ControlBase {
  /**
   * 构造函数
   * @constructor
   * @param {Object} options - 控件配置选项
   * @param {string} options.format - 状态栏格式，显示内容的格式化html展示的内容格式化字符串。
   * 支持以下模版配置：【鼠标所在位置】 经度:{lng}， 纬度:{lat}， 海拔：{alt}米，
   *  【相机的】 方向角度：{heading}， 俯仰角度：{pitch}， 视高：{cameraHeight}米，
   *  【地图的】 层级：{level}，每秒帧率：{fps} (越高越流畅)，延迟：{ms} 毫秒 (越小越流畅)
   * @param {number} options.debounceTime - 鼠标移动更新的防抖时间（毫秒）
   */
  constructor(options = {}) {
    super(options);
    // 存储事件处理器，以便在销毁时清理
    this.handler = null;
    // 默认防抖时间
    this.debounceTime = options.debounceTime || 50;
  }

  /**
   * 初始化状态栏
   * @param {Cesium.Viewer} viewer - Cesium Viewer实例
   * @returns {this}
   */
  init(viewer) {
    // 调用父类的init方法
    super.init(viewer);
    
    // 设置默认格式化字符串
    this.format = this.options.format || 
      "经度:{lng}   |   纬度:{lat}   |    海拔:{alt}米   |   方向角度:{heading}   |   俯仰角度:{pitch}   |  视高:{cameraHeight}米   |   层级:{level}";
    
    // 创建并设置状态栏容器
    const statusBar = document.createElement("div");
    statusBar.id = "cesium-extensions-status-bar";
    statusBar.className = "cesium-extensions-status-bar";
    statusBar.innerHTML = this._formatStatusContent(viewer, viewer.camera.position);
    
    const container = viewer.cesiumWidget.creditContainer;
    container.appendChild(statusBar);
    
    // 设置容器引用，使基类的show/hide/destroy方法可用
    this._setContainer(statusBar);
    
    // 开始监听所有必要事件
    this._setupEventListeners();
    
    return this;
  }
  
  /**
   * 计算标准地图缩放层级（谷歌地图风格）
   * @param {number} cameraHeight - 相机高度
   * @returns {number} 0-22范围内的整数层级
   * @private
   */
  _calculateMapLevel(cameraHeight) {
    try {
      // 避免除以零或负数情况
      if (cameraHeight <= 0) return 0;
      
      // 参考公式: level = 22 - log2(height / 1000)
      const level = Math.round(22 - Math.log2(cameraHeight / 1000));
      // 确保层级在有效范围内（0-22）
      return Math.max(0, Math.min(22, level));
    } catch (error) {
      console.warn('计算地图层级时出错:', error);
      return 0;
    }
  }
  
  /**
   * 获取正确的FPS值
   * @param {Cesium.Viewer} viewer - Cesium Viewer实例
   * @returns {number} 当前FPS值
   * @private
   */
  _getCurrentFps(viewer) {
    // Cesium场景没有直接的FPS属性，这里返回模拟值
    // 实际项目中可以使用性能监测库来获取真实FPS
    return Math.round(viewer.scene.frameRate || 60);
  }
  
  /**
   * 获取渲染延迟
   * @param {Cesium.Viewer} viewer - Cesium Viewer实例
   * @returns {number} 延迟毫秒数
   * @private
   */
  _getCurrentFrameTime(viewer) {
    // 模拟获取帧渲染时间
    return Math.round(1000 / (viewer.scene.frameRate || 60));
  }
  
  /**
   * 格式化状态栏内容
   * @param {Cesium.Viewer} viewer - Cesium Viewer实例
   * @param {Cesium.Cartesian3} position - 位置坐标
   * @returns {string} 格式化后的HTML内容
   * @private
   */
  _formatStatusContent(viewer, position) {
    try {
      // 计算坐标信息
      const cartographic = Cesium.Cartographic.fromCartesian(position);
      const longitude = Cesium.Math.toDegrees(cartographic.longitude);
      const latitude = Cesium.Math.toDegrees(cartographic.latitude);
      const height = cartographic.height;
      
      // 计算相机信息
      const camera = viewer.camera;
      const heading = Cesium.Math.toDegrees(camera.heading);
      const pitch = Cesium.Math.toDegrees(camera.pitch);
      const cameraHeight = viewer.camera.positionCartographic.height;
      
      // 计算层级
      const normalizedLevel = this._calculateMapLevel(cameraHeight);
      
      // 获取性能数据
      const fps = this._getCurrentFps(viewer);
      const ms = this._getCurrentFrameTime(viewer);
      
      // 格式化并返回HTML内容
      return this.format
        .replace(/\{lng\}/g, longitude.toFixed(6))
        .replace(/\{lat\}/g, latitude.toFixed(6))
        .replace(/\{alt\}/g, height.toFixed(2))
        .replace(/\{heading\}/g, heading.toFixed(2))
        .replace(/\{pitch\}/g, pitch.toFixed(2))
        .replace(/\{cameraHeight\}/g, cameraHeight.toFixed(2))
        .replace(/\{level\}/g, normalizedLevel.toString())
        .replace(/\{fps\}/g, fps.toString())
        .replace(/\{ms\}/g, ms.toString());
    } catch (error) {
      console.warn('格式化状态栏内容时出错:', error);
      return '加载中...';
    }
  }
  
  /**
   * 设置事件监听器
   * @private
   */
  _setupEventListeners() {
    const statusBar = document.getElementById("cesium-extensions-status-bar");
    if (!statusBar) return;
    
    // 移除已存在的处理器，避免重复添加
    this._removeEventListeners();
    
    // 创建鼠标事件处理器
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    
    let debounceTimer;
    const self = this;
    
    // 监听鼠标移动事件 - 更新鼠标位置相关信息
    this.handler.setInputAction(function(movement) {
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(() => {
        const cartesian = self.viewer.scene.pickPosition(movement.endPosition);
        if (cartesian) {
          statusBar.innerHTML = self._formatStatusContent(self.viewer, cartesian);
        }
      }, self.debounceTime);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    
    // 监听相机移动结束事件 - 确保相机移动后更新状态栏
    // 这样即使没有鼠标移动（如键盘导航、地图动画等），状态栏也会更新
    this.cameraMoveEndSubscription = this.viewer.camera.moveEnd.addEventListener(() => {
      // 使用相机当前位置作为更新位置
      statusBar.innerHTML = self._formatStatusContent(self.viewer, self.viewer.camera.position);
    });
  }
  
  /**
   * 移除事件监听器
   * @private
   */
  _removeEventListeners() {
    // 清理鼠标事件处理器
    if (this.handler) {
      this.handler.destroy();
      this.handler = null;
    }
    
    // 清理相机移动事件订阅
    if (this.cameraMoveEndSubscription) {
      this.cameraMoveEndSubscription();
      this.cameraMoveEndSubscription = null;
    }
  }
  
  /**
   * 销毁状态栏控件，清理资源
   * @returns {void}
   */
  destroy() {
    // 清理事件监听器
    this._removeEventListeners();
    
    // 调用父类的destroy方法清理DOM和引用
    // 父类会处理this._container的移除和所有引用的清理
    super.destroy();
  }
}
